﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;
using JGSoft.U9CRTAPIEX.DTOs;
using JGSoft.U9CRTAPIEX.DTOs.RequestDTOs;
using JGSoft.U9CRTAPIEX.DTOs.ResultDTOs;
using UFIDA.U9.Base;
using UFIDA.U9.Base.Account;
using UFIDA.U9.Base.Currency;
using UFIDA.U9.Base.SOB;
using UFIDA.U9.CBO.FI.Account;
using UFIDA.U9.CBO.FI.Account.Proxy;
using UFIDA.U9.CBO.FI.BankAccount;
using UFIDA.U9.CBO.FI.DTOs;
using UFIDA.U9.CBO.FI.NaturalAccount;
using UFIDA.U9.CBO.FI.SettlementMethod;
using UFIDA.U9.CBO.Pub.Controller;
using UFIDA.U9.CBO.SCM.Bin;
using UFIDA.U9.CBO.SCM.Item;
using UFIDA.U9.CBO.SCM.PropertyTypes;
using UFIDA.U9.GL.TransToGLService;
using UFIDA.U9.GL.TransToGLService.Proxy;
using UFIDA.U9.ISV.PO;
using UFIDA.U9.ISV.PO.Proxy;
using UFIDA.U9.ISV.TransferInISV;
using UFIDA.U9.ISV.TransferInISV.Proxy;
using UFIDA.U9.PM.PO;
using UFSoft.UBF.AopFrame.Lock;
using UFSoft.UBF.Business;
using UFSoft.UBF.MVC;
using UFSoft.UBF.MVC.Common;
using UFSoft.UBF.PL;
using UFSoft.UBF.PL.Engine;
using UFSoft.UBF.Transactions;
using UFSoft.UBF.Util.DataAccess;

namespace JGSoft.U9CRTAPIEX.Controllers
{
    public class VoucherInController : ApiController
    {

        [HttpPost]
        public ApiResult<List<ResultBase>> GenVoucher([FromBody] List<VoucherRData> paras)
        {
            using (BPForEngine bp = new BPForEngine())
            {
                ContextDTO tdto = new ContextDTO();
                tdto.UserCode = "admin";//取接口传入的用户编码
                tdto.EntCode = "101";//取接口传入的企业编码
                tdto.CultureName = "zh-CN";//固定
                tdto.OrgCode = "101";//取接口传入的组织编码
                tdto.WriteToContext();
                ApiResult<List<ResultBase>> result = new ApiResult<List<ResultBase>>();
                List<ResultBase> rtndatas = new List<ResultBase>();
                try
                {
                    ImportVoucherSvProxy importVoucherSvProxy = new ImportVoucherSvProxy();
                    List<ChainVoucherDTOData> VoucherDTOs = new List<ChainVoucherDTOData>();
                    string errormessage = string.Empty;
                    foreach (var para in paras)
                    {
                        ChainVoucherDTOData chainVoucherDTOData = new ChainVoucherDTOData();
                        chainVoucherDTOData.AttachmentCount = 0;
                        chainVoucherDTOData.CreateDate = Convert.ToDateTime(para.CreateDate);
                        chainVoucherDTOData.VoucherDisplayCode = para.DocNo;

                        AccountPeriod accountPeriod = AccountPeriod.Finder.Find($"FromDate <= '{para.CreateDate}' and ToDate >= '{para.CreateDate}'");
                        chainVoucherDTOData.PostedPeriod = accountPeriod.Year + "-" + accountPeriod.Month + "0";

                        chainVoucherDTOData.DescFlexField = new UFIDA.U9.Base.FlexField.DescFlexField.DescFlexSegmentsData();
                        chainVoucherDTOData.DescFlexField.PrivateDescSeg1 = para.DocNo;
                        SetofBooks setofBooks = SetofBooks.Finder.Find($"SOBType = 0");
                        chainVoucherDTOData.SOB = new IDCodeDTOData { ID = setofBooks.ID,Code = setofBooks.Code };

                        SOBAccountingPeriod sOBAccountingPeriod = SOBAccountingPeriod.Finder.Find($"AccountPeriod = {accountPeriod.ID} and SetofBooks = {setofBooks.ID}");
                        if (sOBAccountingPeriod!= null &&sOBAccountingPeriod.PeriodState != PeriodStateEnum.Opened)
                        {
                            errormessage += $"账簿会计期间{sOBAccountingPeriod.DisplayName}未打开";
                        }

                        chainVoucherDTOData.VoucherCategory = new IDCodeDTOData { Code = "01",SysState  = new ObjectState() };

                        chainVoucherDTOData.SysState = new ObjectState();

                        List<ChainEntryDTOData> chainEntryDTODatas = new List<ChainEntryDTOData>();

                        foreach (var line in para.Lines)
                        {
                            string ermsg = string.Empty;
                            ChainEntryDTOData lineitem = new ChainEntryDTOData();
                            lineitem.Abstracts = line.Abstracts;



							var accountparm = line.Account.Split('|');
							string NaturalAccountCode = accountparm[0];
							string Supplier = accountparm[1];
							string Customer = accountparm[2];
							string Department = accountparm[3];
							string Person = accountparm[4];
							string Project = accountparm[5];
							string BankAccountCode = accountparm[6];
                            string YFProject = accountparm[9];
                            if (NaturalAccountCode == "0")
                            {
                                continue;
                            }
                            NaturalAccountSet naturalAccountSet = NaturalAccountSet.Finder.Find("Code = '1'");
							NaturalAccount naturalAccount = NaturalAccount.Finder.Find($"Code = '{NaturalAccountCode}' and NaturalAccountSet = {naturalAccountSet.ID}");

							NaturalAccountSOBProperty naturalAccountSOBProperty = NaturalAccountSOBProperty.Finder.Find($"SOB = {setofBooks.ID} and NaturalAccount = {naturalAccount.ID}");

							NaturalAccountSOBSegmentUseRole naturalAccountSOBSegmentUseRole = NaturalAccountSOBSegmentUseRole.Finder.Find($"NaturalAccountSOBProperty = {naturalAccountSOBProperty.ID} and SOB = {setofBooks.ID}");

                            string AccountCode = NaturalAccountCode + "|" + (naturalAccountSOBSegmentUseRole != null && naturalAccountSOBSegmentUseRole.Segment2 ? Supplier : "0") + "|" + (naturalAccountSOBSegmentUseRole != null && naturalAccountSOBSegmentUseRole.Segment3 ? Customer : "0") + "|" + (naturalAccountSOBSegmentUseRole != null && naturalAccountSOBSegmentUseRole.Segment4 ? Department : "0") + "|" + (naturalAccountSOBSegmentUseRole != null && naturalAccountSOBSegmentUseRole.Segment5 ? Person : "0") + "|" + (naturalAccountSOBSegmentUseRole != null && naturalAccountSOBSegmentUseRole.Segment6 ? Project : "0") + "|" + (naturalAccountSOBSegmentUseRole != null && naturalAccountSOBSegmentUseRole.Segment7 ? BankAccountCode : "0") + "|0|0|" + (naturalAccountSOBSegmentUseRole != null && naturalAccountSOBSegmentUseRole.Segment10 ? YFProject : "0")+"|0";


							Account account = Account.Finder.Find($"Code like '{AccountCode}%'");
                            if (account == null)
                            {

                                //ermsg += $"找不到名称为{line.Account}的会计科目;";
                                CreateAccountsProxy createAccountsProxy = new CreateAccountsProxy();
                                createAccountsProxy.SOB_SKey = setofBooks.Key;
                                createAccountsProxy.SOB = setofBooks.ID;
                                //createAccountsProxy.SOBVersion = setofBooks.SOBVersion.ID;
                                createAccountsProxy.CombineCodes = new List<string> { AccountCode };
                                //createAccountsProxy.IsBatchLoadVS = true;
                                var accountrtn = createAccountsProxy.Do();
                                if (accountrtn.Count > 0)
                                {
                                    lineitem.Account = new IDCodeDTOData { ID = accountrtn[0].Account.ID, Code = accountrtn[0].Account.Code };
                                }
                                else
                                {
                                    ermsg += $"创建会计科目{line.Account}失败;";
                                }
                            }
                            else
                            {
                                lineitem.Account = new IDCodeDTOData { ID = account.ID, Code = account.Code };
                            }


                            lineitem.EnteredCr = line.EnteredCr;
                            lineitem.EnteredDr = line.EnteredDr;
                            lineitem.AmountCr = line.AmountCr;
                            lineitem.AmountDr = line.AmountDr;

                            if (!string.IsNullOrEmpty(line.BankAccount))
                            {
                                BankAccount bankAccount = BankAccount.Finder.Find($"Code = '{line.BankAccount}'");
                                if (bankAccount == null)
                                {
                                    ermsg += $"找不到编码为{line.BankAccount}的银行账号;";

                                }
                                else
                                {
                                    lineitem.BankAccount = new IDCodeDTOData { ID = bankAccount.ID, Code = bankAccount.Code };
                                }
                            }

                            if (!string.IsNullOrEmpty(line.SettlementMethod))
                            {
                                SettlementMethod settlementMethod = SettlementMethod.Finder.Find($"Name = '{line.SettlementMethod}'");
                                if (settlementMethod == null)
                                {
                                    ermsg += $"找不到名称为{line.SettlementMethod}的结算方式;";

                                }
                                else
                                {
                                    lineitem.SettlementMethod = new IDCodeDTOData { ID = settlementMethod.ID, Code = settlementMethod.Code };

                                }

                            }
                            lineitem.OCToFCExchangeRate = 1;
                            Currency currency = Currency.Finder.Find($"Symbol = '{line.Currency}'");
                            if (currency == null)
                            {
                                ermsg += $"找不到货币符号为{line.Currency}的币种;";

                            }
                            else
                            {
                                lineitem.Currency = new IDCodeDTOData { ID = currency.ID, Code = currency.Code };
                                if (currency.Symbol == "CNY")
                                {
                                    lineitem.OCToFCExchangeRate = 1;
                                }
                                else
                                {
                                    ExchangeRate exchangeRate = ExchangeRate.Finder.Find($"FromCurrency = {currency.ID}");
                                    if (exchangeRate == null)
                                    {
                                        ermsg += $"找不到币种为{currency.Name}的汇率;";

                                    }
                                    else
                                    {
                                        lineitem.OCToFCExchangeRate = exchangeRate.Rate;

                                    }
                                }
                            }
                            lineitem.AccountedCr = line.EnteredCr * lineitem.OCToFCExchangeRate;
                            lineitem.AccountedDr = line.EnteredDr * lineitem.OCToFCExchangeRate;

                            lineitem.ExchangeRateTypes = 2;
                            if (!string.IsNullOrEmpty(ermsg))
                            {
                                errormessage += ermsg;
                                continue;
                            }

                            chainEntryDTODatas.Add(lineitem);
                        }
                        chainVoucherDTOData.ChainEntries = chainEntryDTODatas;

                        VoucherDTOs.Add(chainVoucherDTOData);
                    }
                    if (!string.IsNullOrEmpty(errormessage))
                    {
                        result.ResMsg = errormessage;
                        rtndatas.Add(new ResultBase { IsSucess = false }); ;
                        result.Data = rtndatas;
                        return result;
                    }
                    importVoucherSvProxy.VoucherDTOs = VoucherDTOs;
                    var rtn = importVoucherSvProxy.Do();
                    foreach (var rt in rtn)
                    {
                        rtndatas.Add(new ResultBase { IsSucess = true, ID = rt.ID });
                        string updatesql = $"update GL_Voucher set CreatedBy ='{paras[0].name}',ModifiedBy='{paras[0].name}' where ID = {rt.ID}";
                        DataAccessor.RunSQL(DataAccessor.GetConn(), updatesql, null);
                    }
                    result.Data = rtndatas;
                    return result;
                }
                catch (Exception ex)
                {
                    result.ResMsg = "请检查科目设（辅助核算、核算币种等）及OA单据字段是否填写正确";
                    rtndatas.Add(new ResultBase { IsSucess = false }); ;
                    result.Data = rtndatas;
                    return result;
                    //throw new Exception(ex.Message);
                }
            }
        }

    }
}
